package com.hxkj.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hxkj.dao.*;
import com.hxkj.domain.enums.AuthRoleExceptionEnum;
import com.hxkj.domain.enums.UserExceptionEnum;
import com.hxkj.domain.po.*;
import com.hxkj.service.AuthUserService;
import com.hxkj.token.utils.TokenUtils;
import com.hxkj.utils.MD5Utils;
import com.hxkj.utils.StrSliptUtils;
import com.platform.common.domain.result.ResultDataStruct;
import com.platform.common.domain.result.ResultMessageStruct;
import com.platform.common.domain.to.PageTo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;


/**
 * @ClassName UserAuthServiceImpl
 * @Description TODO
 * @Author Mr.zheng
 * @Date 2018/5/19 15:04
 * @Version 1.0
 */
@Service
@Slf4j
public class AuthUserServiceImpl implements AuthUserService {

    private static final Logger LOGGER = LoggerFactory.getLogger(AuthUserServiceImpl.class);

    @Autowired
    private AuthUserDao authUserDao;

    @Autowired
    private AuthRoleDao ahthRoleDao;

    @Autowired
    private AuthUserRoleAppDao authUserRoleAppDao;

    @Autowired
    private UserSiteDao userSiteDao;

    @Autowired
    private DepartmentDao departmentDao;

    @Autowired
    private SiteDao sitedao;


    @Override
    public PageInfo getAuthUserBySlave(AuthUser authUser, PageTo pageParam) throws Exception {
        //设置分页
        Page<AllocationAuthUser> page = PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize());
        PageInfo<AllocationAuthUser> pageInfo = new PageInfo<>();
        if (authUser.getUserId().equals(1L) && authUser.getSiteId().equals(0L)) {
            // 说明是平台超级管理员并且在云平台下
            List<AuthUser> list = authUserDao.getUserList(authUser);
            //调用方法查用户所有信息集合
            List<AllocationAuthUser> allocationAuthUserList = getAllocationAuthUser(list);
            pageInfo = new PageInfo<>(page);
            pageInfo.setList(allocationAuthUserList);
            return pageInfo;
        } else {
            List<AuthUser> list = authUserDao.getUserListAsSite(authUser);//Mr.zheng:平台超管不能显示在子站
            //调用方法查用户所有信息集合
            List<AllocationAuthUser> allocationAuthUserList = getAllocationAuthUser(list);
            pageInfo = new PageInfo<>(page);
            pageInfo.setList(allocationAuthUserList);
            return pageInfo;
        }
    }

    @Override
    public ResultDataStruct<AllocationAuthUser> getAuthUser(Long uid) throws Exception {
        ResultDataStruct resultDataStruct = new ResultDataStruct();
        AuthUser authUser = authUserDao.get(uid);
        if (authUser == null) {
            resultDataStruct.setCode(302);
            resultDataStruct.setData("用户不存在");
            resultDataStruct.setMessage("用户不存在");
            return resultDataStruct;
        }
        //Mr.zheng:创建用户所有信息关联对象
        AllocationAuthUser allocationAuthUser = new AllocationAuthUser();
        //Mr.zheng:封装用户账号信息
        allocationAuthUser.setAuthUser(authUser);
        //Mr.zheng:封装用户所属角色信息
        List<AuthRole> authRoleList = authUserDao.findAuthRoleByUser(uid);
        if (authRoleList.size() > 0) {
            allocationAuthUser.setAuthRoleList(authRoleList);
        }
        //Mr.zheng:封装用户所分配站点信息
        List<Site> siteList = userSiteDao.getAassignedSite(uid);
        if (siteList.size() > 0) {
            allocationAuthUser.setSiteList(siteList);
        }
        //Mr.zheng:封装用户所属部门信息
        if (authUser.getDepartmentId() != null) {
            allocationAuthUser.setDepartment(departmentDao.get(authUser.getDepartmentId()));
        }
        //Mr.zheng:封装返回信息
        resultDataStruct.setCode(200);
        resultDataStruct.setData(allocationAuthUser);
        resultDataStruct.setMessage("获取用户信息成功");
        return resultDataStruct;
    }


    @Override
    //新增数据，注解开启事务
    @Transactional(rollbackFor = Exception.class)
    public ResultMessageStruct saveAuthUser(AuthUser authUser) throws Exception {
        ResultMessageStruct resultMessageStruct = new ResultMessageStruct();
        //Mr.zheng:判断用户是否已经存在，如果存在则不允许重复添加
        AuthUser authUsers = new AuthUser();
        authUsers.setUserAccount(authUser.getUserAccount());
        List<AuthUser> authUserList = authUserDao.getUserByName(authUsers);
        if (authUserList.size() > 0) {
            resultMessageStruct.setCode(UserExceptionEnum.USER_ARE_EXIST.getCode());
            resultMessageStruct.setMessage(UserExceptionEnum.USER_ARE_EXIST.getMsg());
            return resultMessageStruct;
        } else {
            //Mr.zheng:如果不是云平台创建的账号标记userType为1
            if (authUser.getSiteId() != 0){
                authUser.setUserType((byte) 1);
            }
            authUserDao.save(authUser);
            //Mr.zheng:初始化用户站点信息
            UserSite userSite = new UserSite();
            userSite.setUserId(authUser.getUserId());
            userSite.setSiteId(authUser.getSiteId());
            userSite.setCreateTime(System.currentTimeMillis());
            userSite.setDelTag(0l);
            userSiteDao.save(userSite);
            resultMessageStruct.setCode(200);
            resultMessageStruct.setMessage("用户添加成功");
            return resultMessageStruct;
        }
    }

    @Override
    public void userLock(String uid) throws Exception {

    }


    @Override
    //Mr.zheng:修改数据，注解开启事务
    @Transactional(rollbackFor = Exception.class)
    public ResultMessageStruct updateAuthUser(AuthUser authUser) throws Exception {
        ResultMessageStruct resultMessageStruct = new ResultMessageStruct();
        try {
            //Mr.zheng:判断用户是否为超级管理员
            if (authUser.getUserId() == 1) {
                AuthUser user = authUserDao.get(1L);
                user.setPassword(authUser.getPassword()==null ? null:authUser.getPassword());
                user.setComment(authUser.getComment()==null ? null:authUser.getComment());
                authUserDao.update(user);
                resultMessageStruct.setCode(200);
                resultMessageStruct.setMessage("修改超级管理员密码成功(注:超级管理员只能修改密码)");
                return resultMessageStruct;
            }
            //Mr.zheng:根据用户ID查询用户数据
//            AuthUser authUser01 = authUserDao.get(authUser.getUserId());
            //Mr.zheng:判断用户账号是否有修改
//            if (authUser01.getUserAccount().equals(authUser.getUserAccount())) {
////                //Mr.zheng:账号一致，则没有修改账号，直接操作其他数据修改
////                authUserDao.update(authUser);
////                resultMessageStruct.setCode(200);
////                resultMessageStruct.setMessage("修改用户信息成功");
////                return resultMessageStruct;
////            }
            //Mr.zheng:判断用户账号是否已经存在，如果存在则不允许修改重复
//            AuthUser authUsers = new AuthUser();
//            authUsers.setUserAccount(authUser.getUserAccount());
//            List<AuthUser> authUserList = authUserDao.getUserList(authUsers);
//            if (authUserList.size() > 0) {
//                resultMessageStruct.setCode(UserExceptionEnum.USER_ARE_EXIST.getCode());
//                resultMessageStruct.setMessage(UserExceptionEnum.USER_ARE_EXIST.getMsg());
//                return resultMessageStruct;
//            }
            /*if(authUser.getUserAccount() != null){
                authUser.setUserAccount(null);
            }*/
            //Mr.zheng:根据用户ID获取用户的账号和盐，对修改的密码进行加密
            AuthUser aut = authUserDao.get(authUser.getUserId());
            if(StringUtils.isNotEmpty(authUser.getPassword())) {
                authUser.setUserAccount(aut.getUserAccount());
                authUser.setSalt(aut.getSalt());
            }
            authUserDao.update(authUser);
            resultMessageStruct.setCode(200);
            return resultMessageStruct;
        } catch (Exception e) {
            e.printStackTrace();
            resultMessageStruct.setCode(UserExceptionEnum.UPDATE_USER_ERROR.getCode());
            resultMessageStruct.setMessage(UserExceptionEnum.UPDATE_USER_ERROR.getMsg());
            return resultMessageStruct;
        }
    }

    @Override
    //Mr.zheng:删除数据，注解开启事务
    @Transactional(rollbackFor = Exception.class)
    public ResultMessageStruct deleteAuthUser(AuthUser authUser) throws Exception {
        ResultMessageStruct resultMessageStruct = new ResultMessageStruct();
        try {
            //Mr.zheng:切割用户id字符串
            String[] str = StrSliptUtils.sliptArray(authUser.getUids());
            //Mr.zheng:遍历用户ID将所有用户信息删除
            for (int i = 0; i < str.length; i++) {
                Long uid = Long.valueOf(str[i]);
                //Mr.zheng:超级管理员无法删除
                if (uid == 1) {
                    resultMessageStruct.setCode(308);
                    return resultMessageStruct;
                }
                authUserDao.delete(uid);
                //Mr.zheng:执行删除与用户关联表的数据
                //Mr.zheng:1、删除与用户关联的站点
                UserSite userSite = new UserSite();
                userSite.setUserId(uid);
                userSiteDao.delete(userSite);
                //Mr.zheng:2、清除与用户关联的角色与app
                AuthUserRoleApp authUserRoleApp = new AuthUserRoleApp();
                authUserRoleApp.setUserId(uid);
                authUserRoleAppDao.delete(authUserRoleApp);
            }
            resultMessageStruct.setCode(200);
            resultMessageStruct.setMessage("用户删除成功");
            return resultMessageStruct;
        } catch (Exception e) {
            e.printStackTrace();
            resultMessageStruct.setCode(UserExceptionEnum.DELETE_USER_ERROR.getCode());
            resultMessageStruct.setMessage(UserExceptionEnum.DELETE_USER_ERROR.getMsg());
            return resultMessageStruct;
        }

    }

    @Override
    //查询用户已关联的角色
    public List<AuthRole> findAuthRoleByUser(AuthUser authUser) throws Exception {
        List<AuthRole> authRoles = authUserDao.findAuthRoleByUser(authUser.getUserId());
        return authRoles;
    }

    @Override
    //关联用户到角色
    @Transactional(rollbackFor = Exception.class)
    public ResultMessageStruct addUsertToRole(AuthRole authRole) throws Exception {

        ResultMessageStruct resultMessageStruct = new ResultMessageStruct();
        try {
            //查询角色是否已经被禁用
            AuthRole ro = ahthRoleDao.get(authRole.getRoleId());
            if (ro.getRoleStatus()!=0){
                resultMessageStruct.setCode(AuthRoleExceptionEnum.ROLE_USER_ERROR.getCode());
                resultMessageStruct.setMessage(AuthRoleExceptionEnum.ROLE_USER_ERROR.getMsg());
                return resultMessageStruct;
            }

            //清空该角色关联的所有用户(关联表)
            AuthUserRoleApp userRole = new AuthUserRoleApp();
            userRole.setRoleId(authRole.getRoleId());
            //清空该角色关联的所有用户之前,要把清空的用户的关联状态role_tag修改为未关联状态0
            //首先找到该角色关联的所有用户
            AuthUserRoleApp userRoleApp = new AuthUserRoleApp();
            userRoleApp.setRoleId(authRole.getRoleId());
            List<AuthUserRoleApp> authUserRoleApps = authUserRoleAppDao.get(userRoleApp);
            for (AuthUserRoleApp authUserRoleApp : authUserRoleApps) {
                AuthUser user = new AuthUser();
                user.setUserId(authUserRoleApp.getUserId());
                user.setRoleTag(0);
                authUserDao.updateUser(user);
            }
            authUserRoleAppDao.delete(userRole);


            if (org.apache.commons.lang3.StringUtils.isBlank(authRole.getUserIds())) {
                resultMessageStruct.setCode(200);
                return resultMessageStruct;
            }
            //解析批量操作的账号id
            String[] userIdArry = authRole.getUserIds().split(",");
            for (String userid : userIdArry) {
                //更改用户标识为已关联角色
                AuthUser user = new AuthUser();
                user.setUserId(Long.valueOf(userid));
                user.setRoleTag(1);
                authUserDao.updateUser(user);

                AuthUserRoleApp authUserRoleApp = new AuthUserRoleApp();
                authUserRoleApp.setCreateTime(System.currentTimeMillis());
                authUserRoleApp.setRoleId(authRole.getRoleId());
                authUserRoleApp.setUserId(Long.valueOf(userid));
                authUserRoleApp.setAppId(1L);
                authUserRoleAppDao.save(authUserRoleApp);
            }
            resultMessageStruct.setCode(200);
            resultMessageStruct.setMessage("分配用户成功");
            return resultMessageStruct;
        } catch (Exception e) {
            e.printStackTrace();
            resultMessageStruct.setCode(UserExceptionEnum.ROLE_ASSIGN_USER_ERROR.getCode());
            return resultMessageStruct;
        }

    }

    @Override
    public ResultDataStruct<AllocationUser> getRoleAssignUser(AuthRole authRole) throws Exception {
        ResultDataStruct<AllocationUser> result = new ResultDataStruct<>();
        //查询角色是否已经被禁用
        AuthRole ro = ahthRoleDao.get(authRole.getRoleId());
        if (ro.getRoleStatus()!=0){
            result.setCode(AuthRoleExceptionEnum.ROLE_USER_ERROR.getCode());
            result.setMessage(AuthRoleExceptionEnum.ROLE_USER_ERROR.getMsg());
            return result;
        }
        List<Long> userIds = new ArrayList<>();
        AllocationUser allocationUser = new AllocationUser();
        //查询该角色关联的所有用户
        List<AuthUser> roleUsers1 = authUserDao.findUserByAuthRole(authRole);
        //该角色还没有关联的所有用户,由于前端取数据,已经分配的是从未分配的数据中取出来的
        List<AuthUser> noRoleUsers = authUserDao.findNoRoleUser(authRole);
        for (AuthUser user : roleUsers1) {
            userIds.add(user.getUserId());
            noRoleUsers.add(user);
        }
        allocationUser.setRoleUsers(userIds);
        //一个用户只能关联一个角色,一个角色可以对应多个用户,查询还没有关联该角色的用户
        allocationUser.setNoRoleUsers(noRoleUsers);
        result.setData(allocationUser);
        result.setMessage("获取关联角色的用户信息成功");
        result.setCode(200);
        return result;


    }

    //获取所有自媒体角色账号和,已经分配了小程序的自媒体账号
    @Override
    public PageInfo<AuthUserAgent> getAgentList(AuthUserAgent authUserAgent, PageTo pageParam) throws Exception {
        //前端没有传分页参数,默认设置第一页,取10条
        if (pageParam.getPageNum() == null || pageParam.getPageSize() == null) {
            pageParam.setPageNum(1);
            pageParam.setPageSize(10);
        }
        try {
            Page<AuthUserAgent> page = PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize());
            PageInfo<AuthUserAgent> pageInfo = null;
            List<AuthUserAgent> agentUsers = authUserDao.getAgentList(authUserAgent);
            pageInfo = new PageInfo<>(page);
            pageInfo.setList(agentUsers);
            return pageInfo;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    @Override
    public ResultDataStruct<AuthRole> getAuthRoleByUser(AuthUser authUser) throws Exception {
        ResultDataStruct<AuthRole> resultDataStruct = new ResultDataStruct<>();
        try {
            List<AuthRole> authRoleList = authUserDao.getAuthRoleByUser(authUser);
            resultDataStruct.setData(authRoleList.get(0));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultDataStruct;
    }

    @Override
    public ResultDataStruct<Site> getSiteById(Site site) throws Exception {
        ResultDataStruct<Site> resultDataStruct = new ResultDataStruct<>();
        try {
            Site site1 = sitedao.getSiteById(site.getSiteId());
            resultDataStruct.setData(site1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultDataStruct;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultMessageStruct updateAuthUserPassword(AuthUser authUser) {
        ResultMessageStruct resultMessageStruct = new ResultMessageStruct();
        try {
            //Mr.zheng:根据用户ID查询用户数据
            AuthUser authUser01 = authUserDao.getUserPassword(authUser.getUserId());
            if (authUser01==null){
                resultMessageStruct.setCode(UserExceptionEnum.USER_NOT_EXIST.getCode());
                return resultMessageStruct;
            }
            //调用MD5工具类对密码加密
            String password = MD5Utils.getEncryptedPwd(authUser.getPassword(), authUser01.getCredentialsSalt());
            if (!password.equals(authUser01.getPassword())){
                resultMessageStruct.setCode(UserExceptionEnum.USER_PASSWORD_IS_NO.getCode());
                return resultMessageStruct;
            }
            //Mr.zheng:将新密码放入对象，去修改
            authUser01.setPassword(authUser.getNewPassword());
            authUserDao.update(authUser01);
            resultMessageStruct.setCode(200);
            return resultMessageStruct;
        } catch (Exception e) {
            e.printStackTrace();
            resultMessageStruct.setCode(UserExceptionEnum.UPDATE_PASSWORD_ERROR.getCode());
            return resultMessageStruct;
        }
    }



    //Mr.zheng:根据用户信息查询用户所有关联信息的方法
    private List<AllocationAuthUser> getAllocationAuthUser(List<AuthUser> authUserList) throws Exception {
        List<AllocationAuthUser> allocationAuthUserList = new ArrayList<>();
        for (AuthUser user : authUserList) {
            //Mr.zheng:创建用户所有信息关联对象
            AllocationAuthUser allocationAuthUser = new AllocationAuthUser();
            //Mr.zheng:封装用户账号信息
            allocationAuthUser.setAuthUser(user);
            //Mr.zheng:封装用户所属角色信息
            List<AuthRole> authRoleList = authUserDao.findAuthRoleByUser(user.getUserId());
            if (authRoleList.size() > 0) {
                allocationAuthUser.setAuthRoleList(authRoleList);
            }
            //Mr.zheng:封装用户所分配站点信息
            List<Site> siteList = userSiteDao.getAassignedSite(user.getUserId());
            if (siteList.size() > 0) {
                allocationAuthUser.setSiteList(siteList);
            }
            //Mr.zheng:封装用户所属部门信息
            if (user.getDepartmentId() != null) {
                allocationAuthUser.setDepartment(departmentDao.get(user.getDepartmentId()));
            }
            //Mr.zheng:将用户信息方法list集合
            allocationAuthUserList.add(allocationAuthUser);

        }
        return allocationAuthUserList;
    }
}
